package com.mingqijia.gassafety.webserver.service.impl;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.base.CommonResponse;
import com.gap.basic.exception.BizException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.BusinessNotice;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.DtuValveRecord;
import com.mingqijia.gassafety.db.entity.ValveInfo;
import com.mingqijia.gassafety.db.entity.vo.ValveInfoListVO;
import com.mingqijia.gassafety.db.mapper.ValveInfoMapper;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.PageColumnConst;
import com.mingqijia.gassafety.shared.dto.LogVO;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageColumns;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.request.ValveInfoAddRequest;
import com.mingqijia.gassafety.webserver.request.ValveInfoRequest;
import com.mingqijia.gassafety.webserver.service.DtuValveRecordService;
import com.mingqijia.gassafety.webserver.service.EquipmentService;
import com.mingqijia.gassafety.webserver.service.ValveInfoService;
import com.mingqijia.gassafety.webserver.utils.LogRecordAspect;
import com.mingqijia.gassafety.webserver.utils.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.stream.Collectors;

/**
 * <p>
 * 电磁阀信息表 服务实现类
 * </p>
 *
 * @author li.shiying
 * @since 2023-08-22
 */
@Service
@Slf4j
public class ValveInfoServiceImpl extends ServiceImpl<ValveInfoMapper, ValveInfo> implements ValveInfoService {

    @Autowired
    ValveInfoMapper valveInfoMapper;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    EquipmentService equipmentService;
    @Autowired
    DtuValveRecordService dtuValveRecordService;

    @Override
    public PageUtil<ValveInfoListVO> getList(ValveInfoRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();

        Page<ValveInfoListVO> page = PageHelper.startPage(req.getPage(), req.getPageSize());
        List<ValveInfoListVO> list = valveInfoMapper.getValveInfoList(req.getValveName(),
                req.getValveModel(),req.getValveManufacturer(),spId);

        //电磁阀厂家
        List<DictionaryItemRespDTO> dictList = holder.getDictionaryByKeyNoCache(
                Constants.VALVE_MANUFACTURER, spId);
        for (ValveInfoListVO valveInfoListVO : list) {
            valveInfoListVO.setValveManufacturerName(getName(dictList, valveInfoListVO.getValveManufacturer()));
        }
        List<PageColumns> pageColumns = PageColumnConst.add(PageColumnConst.valveInfoListTitles, PageColumnConst.valveInfoListIndices);

        PageUtil pageInfo = new PageUtil<>(req.getPage(), req.getPageSize(), page.getTotal(), list, pageColumns);
        return pageInfo;
    }

    @Override
    public void add(ValveInfoAddRequest req) {
        //企业级操作日志
        LogVO vo = new LogVO();
        vo.setDetail("设备");
        vo.setCommonInfo(req.getValveName());
        LogRecordAspect.threadLocal.set(vo);

        String spId = ApplicationUtils.getWorkingSpId();

        ValveInfo valveInfo = new ValveInfo();
        BeanUtils.copyProperties(req, valveInfo);

        LambdaQueryWrapper<ValveInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ValveInfo::getSpId, spId).eq(ValveInfo::getIsDeleted, Constants.IS_DELETED_FALSE)
                .eq(ValveInfo::getValveName,req.getValveName());
        Integer count = this.count(wrapper);
        if (count > 0) {
            throw new BizException(req.getValveName() + "已存在！");
        }
        valveInfo.setSpId(spId);
        log.info("电磁阀信息新增："+valveInfo);
        this.save(valveInfo);

        //企业级操作日志
        LogVO vo2 = new LogVO();
        vo2.setDetail("【电磁阀名称："+ req.getValveName()+"】\n"+
                LogUtil.addOrDeleteEntity(valveInfo, ValveInfo.class));
        vo2.setCommonInfo(req.getValveName());
        LogRecordAspect.threadLocal.set(vo2);
    }

    @Override
    @Transactional
    public void remove(Integer id) {
        String spId = ApplicationUtils.getWorkingSpId();

        ValveInfo valveInfo = new ValveInfo();
        valveInfo.setId(id);
        valveInfo.setIsDeleted(true);
        log.info("电磁阀信息删除："+valveInfo);
        Boolean updateRst = this.updateById(valveInfo);
        if (updateRst) {
            Integer page = 1;
            Integer pageSize = 100;
            List<Dtu> list = getDtuList(id,spId,page,pageSize);
            while (!list.isEmpty()) {
                list = getDtuList(id,spId,page,pageSize);
            }
        }
    }

    private List<Dtu> getDtuList(Integer id,String spId,Integer page,Integer pageSize){
        PageHelper.startPage(page, pageSize);
        LambdaQueryWrapper<Dtu> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(Dtu::getValveInfoId,id).eq(Dtu::getIsDeleted, Constants.IS_DELETED_FALSE)
                .eq(Dtu::getSpId,spId);
        page++;
        List<Dtu> list = equipmentService.list(wrapper2);
        List<DtuValveRecord> dtuValveRecords = new ArrayList<>();
        List<Dtu> dtus = new ArrayList<>();
        for (Dtu dtu : list) {
            DtuValveRecord dtuValveRecord = new DtuValveRecord();
            dtuValveRecord.setDeviceId(dtu.getIMEI());
            dtuValveRecord.setValveId(id);
            dtuValveRecord.setEvent(0);
            dtuValveRecord.setOperationPersonCode(ApplicationUtils.getWorkingUser().getName());
            dtuValveRecord.setOperationPersonName(ApplicationUtils.getWorkingUser().getUsername()+"删除电磁阀");
            dtuValveRecord.setSpId(spId);
            dtuValveRecords.add(dtuValveRecord);
            log.info("电磁阀删除，dtuValveRecord insert：" + dtuValveRecord);

            Dtu dtuUpdate = new Dtu();
            dtuUpdate.setValveInfoId(0);
            dtuUpdate.setId(dtu.getId());
            dtus.add(dtuUpdate);
            log.info("电磁阀删除，Dtu update：" + dtuUpdate);
        }
        if (CollectionUtils.isEmpty(dtuValveRecords)) return list;
        if (dtuValveRecordService.saveBatch(dtuValveRecords)) {
            equipmentService.updateBatchById(dtus);
        }
        return list;
    }
    @Override
    public void edit(ValveInfoAddRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();

        ValveInfo valveInfo = new ValveInfo();
        BeanUtils.copyProperties(req, valveInfo);

        LambdaQueryWrapper<ValveInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ValveInfo::getSpId,spId).eq(ValveInfo::getIsDeleted,0)
                .eq(ValveInfo::getId,req.getId());
        ValveInfo checkInfo = this.getOne(queryWrapper);
        if (checkInfo == null) {
            throw new BizException("编辑的数据不存在！");
        }

        //企业级操作日志
        LogVO vo = new LogVO();
        vo.setDetail("【电磁阀名称："+ checkInfo.getValveName()+"】信息");
        vo.setCommonInfo(checkInfo.getValveName());
        LogRecordAspect.threadLocal.set(vo);

        LambdaQueryWrapper<ValveInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ValveInfo::getSpId, spId).eq(ValveInfo::getIsDeleted, Constants.IS_DELETED_FALSE)
                .eq(ValveInfo::getValveName,req.getValveName());
        ValveInfo info = this.getOne(wrapper);
        if (info !=null && !info.getId().equals(req.getId())) {
            throw new BizException(req.getValveName() + "已存在！");
        }



        LambdaQueryWrapper<ValveInfo> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(ValveInfo::getSpId, spId).eq(ValveInfo::getIsDeleted, Constants.IS_DELETED_FALSE)
                .eq(ValveInfo::getId,req.getId());
        Integer count2 = this.count(wrapper2);
        if (count2 > 0) {
            log.info("电磁阀信息编辑："+valveInfo);
            this.updateById(valveInfo);
            //企业级操作日志
            LogVO vo2 = new LogVO();
            vo2.setDetail("【电磁阀名称："+ checkInfo.getValveName()+"】信息\n"+
                    LogUtil.compareEntity(valveInfo,checkInfo, ValveInfo.class));
            vo2.setCommonInfo(valveInfo.getValveName());
            LogRecordAspect.threadLocal.set(vo2);
        }
    }

    @Override
    public List<String> getModelList() {
        List<String> resultList = new ArrayList<>();
        String spId = ApplicationUtils.getWorkingSpId();
        QueryWrapper<ValveInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct valve_model").lambda().eq(ValveInfo::getSpId,spId).eq(ValveInfo::getIsDeleted, Constants.IS_DELETED_FALSE);
        List<ValveInfo> list = this.list(queryWrapper);
        for (ValveInfo valveInfo : list) {
            resultList.add(valveInfo.getValveModel());
        }
        return resultList;
    }

    @Override
    public ValveInfo getInfoById(Integer valveInfoId) {
        ValveInfo info = this.getById(valveInfoId);
        List<DictionaryItemRespDTO> dtos = holder.getDictionaryByKey(Constants.VALVE_MANUFACTURE_CODE).stream().
                filter(item -> info.getValveManufacturer().equals(item.getValue())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(dtos)){
            info.setValveManufacturer(null);
        }else {
            info.setValveManufacturer(dtos.get(0).getName());
        }
        return info;
    }

    /**
     * 批量获取电磁阀信息
     *
     * @param valveInfoIds
     * @param spId
     * @return
     */
    @Override
    public Map<Integer, ValveInfo> getValveInfo(List<Integer> valveInfoIds, String spId) {
        Map<Integer, ValveInfo> res=new HashMap<>();
        LambdaQueryWrapper<ValveInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(ValveInfo::getSpId,spId).eq(ValveInfo::getIsDeleted,0)
                .in(ValveInfo::getId,valveInfoIds);
        List<ValveInfo> valveInfos = valveInfoMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(valveInfos)) return  null;
        for (ValveInfo valveInfo : valveInfos) {
            res.put(valveInfo.getId(),valveInfo);
        }
        return res;
    }

    private String getName(List<DictionaryItemRespDTO> list, String  value) {
        if( !CollectionUtils.isEmpty(list)){
            List<DictionaryItemRespDTO> respDTOS = list.stream()
                    .filter(dict -> dict.getValue().equals(value)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(respDTOS)){
                return respDTOS.get(0).getName();
            }
        }
        return null;
    }
}
